<template>
  <div class="chart">
    <div class="box mb-30">
      <div class="flex flex-rb">
        <div>
          <span>实时金价：</span>
          <span class="price price--sm price--error">
            {{ goldInfo.realTimePrice }}
          </span>
        </div>

        <span class="price price--sm" v-if="goldInfo.todayIncrease >= 0">
          +{{ goldInfo.todayIncrease || '0.00' }}%
        </span>
        <span
          class="price price--sm price--error"
          v-else-if="goldInfo.todayIncrease < 0"
        >
          {{ goldInfo.todayIncrease || '0.00' }}%
        </span>
      </div>

      <!-- 实时走势图 -->
      <div class="bcl-white mt-10">
        <Base-Chart style="height: 150px" :options="echartOptions"></Base-Chart>
        <div class="x flex flex-rb fz-12 cl-black">
          <span>20:00</span>
          <span>02:30/09:00</span>
          <span>15:30</span>
        </div>
      </div>
    </div>

    <!-- 操作 -->
    <div>
      <div class="flex flex-rc mb-10">
        <van-button
          class="mr-30"
          type="primary"
          @click=";(tradeType = 1), (tradeVisible = true)"
        >
          买入
        </van-button>

        <van-button
          type="primary"
          @click=";(tradeType = 2), (tradeVisible = true)"
        >
          卖出
        </van-button>
      </div>

      <div class="flex flex-rc">
        <van-button type="primary" @click="router.push('/product/index')">
          兑换实物
        </van-button>
      </div>
    </div>

    <!-- 买入、卖出 -->
    <van-popup
      round
      closeable
      :close-on-click-overlay="false"
      v-model:show="tradeVisible"
    >
      <div class="p-15 pt-50 cl-black" style="width: 300px">
        <div v-if="tradeType === 1">
          <div class="fz-16 fw-bold mb-10">买入金额</div>

          <div class="input radius flex flex-cc mb-10">
            <van-field
              type="number"
              :placeholder="`最多可买入${amount}元`"
              @input="limite"
              v-model="price"
            ></van-field>
            <div class="flex-fs-0 pl-10 pr-10 click" @click="all">全部</div>
          </div>

          <div class="flex flex-rb mb-30">
            <div>预计买入}</div>
            <div>{{ canBuyNum }}克</div>
          </div>

          <div class="mb-10">
            <span>确认订单：</span>
            <span>
              {{ goldInfo.confirmDay }}({{
                goldInfo.confirmWeek
              }})的价格计算克数
            </span>
          </div>
          <div class="mb-10">
            <span>订单生效：</span>
            <span>
              {{ goldInfo.effectiveDay }}({{ goldInfo.effectiveWeek }})确认买入
            </span>
          </div>
          <div class="mb-10">
            <span>买入费率：</span>
            <span>{{ goldInfo.fees }}%</span>
          </div>
          <div>
            基金公司将收取买入手续费，此费用使用途径： 管理费，托管费，销售费
          </div>
        </div>

        <div v-else>
          <div class="fz-16 fw-bold mb-10">卖出克数</div>

          <div class="input radius flex flex-cc mb-10">
            <van-field
              type="number"
              :placeholder="`最多可卖出${userInfo.holdingGram}克`"
              @input="limite"
              v-model="num"
            ></van-field>
            <div class="flex-fs-0 pl-10 pr-10 click" @click="all">全部</div>
          </div>

          <div class="flex flex-rb mb-30">
            <div>预计卖出</div>
            <div>{{ canBuyPrice }}元</div>
          </div>

          <div class="mb-10">
            <span>确认订单：</span>
            <span>
              {{ goldInfo.confirmDay }}({{ goldInfo.confirmWeek }})
              的克数计算价格
            </span>
          </div>
          <div class="mb-10">
            <span>订单生效：</span>
            <span>
              {{ goldInfo.effectiveDay }}({{ goldInfo.effectiveWeek }})确认卖出
            </span>
          </div>
          <div class="mb-10">
            <span>买入费率：</span>
            <span>{{ goldInfo.fees }}%</span>
          </div>
          <div>
            基金公司将收取卖出手续费，此费用使用途径： 管理费，托管费，销售费
          </div>
        </div>

        <div class="flex flex-center mt-30">
          <van-button type="primary" @click="submit">确定</van-button>
        </div>
      </div>
    </van-popup>
  </div>
</template>

<script setup>
import { ref, inject } from 'vue'
import goldApi from 'js/gold.api'
import {
  showToast,
  showError,
  showLoading,
  toNumber,
  toBigNumber,
} from 'js/utils'
import testData from './data'

const emit = defineEmits(['refresh'])
const router = useRouter()

// 用户信息
const userInfo = inject('userInfo')

// 黄金信息
const goldInfo = ref({})

// 实时走势图
const echartOptions = ref({})

// 用户钱包余额
const amount = ref('')

// 买入数据
const price = ref('')
const canBuyNum = computed(() => {
  return Number(price.value / goldInfo.value.realTimePrice).toFixed(2)
})

// 卖出数据
const num = ref('')
const canBuyPrice = computed(() => {
  return Number(num.value * goldInfo.value.realTimePrice).toFixed(2)
})

const tradeType = ref(1)
const tradeVisible = ref(false)

initPage()

async function initPage() {
  getGoldInfo()
  amount.value = await getUserAmount()
}

// 获取黄金信息
async function getGoldInfo() {
  const { code, data } = await goldApi.getGoldList()

  if (code === 200) {
    goldInfo.value = data[0]

    // const { todayPriceTrend = [] } = goldInfo.value
    const todayPriceTrend = testData

    const prices = todayPriceTrend
      .filter((v) => typeof v.priceTrend === 'number')
      .map((v) => v.priceTrend)
    const min = Math.min(...prices)
    const max = Math.max(...prices)

    // 更新走势图
    echartOptions.value = {
      grid: {
        top: 20,
        left: 20,
        right: 20,
        bottom: 0,
        containLabel: true,
      },

      tooltip: {
        trigger: 'axis',
        formatter: (v) => {
          return `${v[0].axisValue} ${v[0].data}元/克`
        },
      },

      xAxis: {
        type: 'category',
        show: false,
        data: todayPriceTrend.map((v) => v.minute),
      },

      yAxis: {
        type: 'value',
        min,
        max,
        axisLabel: {
          color: '#151722',
          fontSize: 12,
          interval: 4,
          formatter: (v) => {
            return Number(v).toFixed(2)
          },
        },
        splitNumber: 4,
      },

      series: [
        {
          type: 'line',
          showSymbol: false,
          lineStyle: {
            width: 1,
            color: '#f7b501',
          },
          data: todayPriceTrend.map((v) => v.priceTrend),
        },
      ],
    }
  }
}

// 买入、卖出
async function submit() {
  let payAmount = 0
  let realPayAmount = 0

  if (tradeType.value === 1) {
    if (!Number(price.value)) {
      return showToast('请输入买入金额')
    }

    payAmount = Number(price.value)
    realPayAmount = payAmount
  }

  if (tradeType.value === 2) {
    if (!Number(num.value)) {
      return showToast('请输入卖出克数')
    }

    payAmount = 0.00001
    realPayAmount = Number(num.value)
  }

  const loading = showLoading()

  try {
    // 判断用户Usdt授权给Order的额度是否足够，不够就先授权额度
    const authorizedBalanceByUsdt = await getAuthorizedBalanceByUsdt()

    if (authorizedBalanceByUsdt <= 0) {
      // 需要授权额度
      await authorizeBalanceByUsdt()
    } else if (authorizedBalanceByUsdt < Number(payAmount)) {
      // 可用额度小于用户投资的金额
      await authorizeBalanceByUsdt()
    }

    // 下单
    await investAmount(payAmount, realPayAmount)

    loading?.close()
  } catch (err) {
    console.error(err)
    loading?.close()
  }
}

// 下单
function investAmount(payAmount, realPayAmount) {
  return new Promise(async (resolve, reject) => {
    try {
      console.log(`支付金额：${payAmount}`)

      const res = await orderContract.context.methods
        .invest(
          payAmount,
          tradeType.value === 1
            ? `order-buy-${realPayAmount}`
            : `operate-sell-${realPayAmount}`
        )
        .send({
          from: fromAddress,
        })

      price.value = ''
      num.value = ''
      tradeVisible.value = false
      showSuccess('支付成功')
      console.log('支付成功')
      console.log(res)

      setTimeout(() => {
        emit('refresh')
        initPage()
      }, 1500)

      resolve(res)
    } catch (err) {
      showError('支付失败')
      console.error('支付失败')
      console.error(err)
      reject(err)
    }
  })
}

// 全部
function all() {
  let max = 0

  if (tradeType.value === 1) {
    max = Number(amount.value)
  } else {
    max = Number(userInfo.value.holdingGram)
  }

  if (tradeType.value === 1) {
    price.value = max == 0 ? '' : max
  } else {
    num.value = max == 0 ? '' : max
  }
}

// 最大值
function limite() {
  let value = 0
  let max = 0

  if (tradeType.value === 1) {
    value = Number(price.value)
    max = Number(amount.value)
  } else {
    value = Number(num.value)
    max = Number(userInfo.value.holdingGram)
  }

  if (value <= 0) {
    if (tradeType.value === 1) {
      price.value = ''
    } else {
      num.value = ''
    }
  } else if (value > max) {
    if (tradeType.value === 1) {
      price.value = max == 0 ? '' : max
    } else {
      num.value = max == 0 ? '' : max
    }

    showToast('超出最大值')
  }
}

// 获取用户钱包余额
function getUserAmount() {
  return new Promise(async (resolve, reject) => {
    try {
      console.log('获取账户余额')
      const balance = await usdtContract.context.methods
        .balanceOf(fromAddress)
        .call()
      const balanceInBigNumber = toNumber(balance)
      console.log(`获取账户余额成功：${balanceInBigNumber}`)
      resolve(balanceInBigNumber)
    } catch (err) {
      showError('获取账户余额失败')
      console.error('获取账户余额失败')
      console.error(err)
      reject(err)
    }
  })
}

// Usdt授权Order额度
function authorizeBalanceByUsdt() {
  return new Promise(async (resolve, reject) => {
    try {
      const quota = toBigNumber(100000) // 授权 100000 Usdt额度
      const res = await usdtContract.context.methods
        .approve(orderContract.context._address, quota)
        .send({
          from: fromAddress,
        })
      showSuccess('授权余额成功')
      console.log(`授权Usdt余额成功：${toNumber(quota)}`)
      console.log(res)
      resolve(quota)
    } catch (err) {
      showError('授权余额失败')
      console.error('授权Usdt余额失败')
      console.error(err)
      reject(err)
    }
  })
}

// 获取Usdt授权给Order的额度
function getAuthorizedBalanceByUsdt() {
  return new Promise(async (resolve, reject) => {
    try {
      const authorizedBalance = await usdtContract.context.methods
        .allowance(fromAddress, orderContract.context._address)
        .call()
      const authorizedBalanceInBigNumber = Number(toNumber(authorizedBalance))
      console.log(`获取Usdt授权余额成功：${authorizedBalanceInBigNumber}`)
      resolve(authorizedBalanceInBigNumber)
    } catch (err) {
      showError('获取授权余额失败')
      console.error('获取Usdt授权余额失败')
      console.error(err)
      reject(err)
    }
  })
}
</script>

<style lang="scss" scoped>
.x {
  padding-left: 65px;
  padding-right: 20px;
  transform: translateY(-10px);
}

.input {
  background-color: rgb(48, 57, 98, 0.75);

  :deep(.van-field) {
    background-color: transparent;

    input {
      color: var(--color-white);
    }
  }
}
</style>
